<?php
namespace auth;

use security\exception\UnAuthorizationException;
use Exception;

class SimpleJwtAuthenticator
{
    /**
     * 判断是否认证
     * @param array $argv
     * @return bool
     * @throws Exception
     */
    public static function isAuthenticate($argv = []) {
        try {
            self::checkAuthenticate($argv);
            return true;
        } catch (UnAuthorizationException $e) {
            return false;
        }
    }

    /**
     * 获取认证标识
     * @param array $argv
     * @return mixed
     * @throws Exception
     */
    public static function getAuthenticator($argv = []) {
        return self::checkAuthenticate($argv);
    }

    public static function getTokenExpiry($argv = []) {
        $jwtKey = $argv['jwt_key'];
        $token = JwtHandler::checkJwtFromHeader($jwtKey);
        if(empty($token)) return 0;
        if(empty($token['expiry'])) return 0;
        return $token['expiry'];
    }

    /**
     * @param array $argv
     * @return array|string
     * @throws Exception
     * @throws UnAuthorizationException
     */
    public static function checkAuthenticate($argv = []) {
        if(!key_exists('jwt_key', $argv) || !is_string($argv['jwt_key']) || trim($argv['jwt_key']) == '')
            throw new Exception("need jwt_key string");
        if(!key_exists('tag', $argv) || !is_string($argv['tag']) || trim($argv['tag']) == '')
            throw new Exception("need tag string");
        if(!key_exists('key', $argv) || !is_string($argv['key']) || trim($argv['key']) == '')
            throw new Exception("need key string");

        $jwtKey = $argv['jwt_key'];
        $key = $argv['key'];

        $token = JwtHandler::checkJwtFromHeader($jwtKey);
        if ($token == null) {
            throw new UnAuthorizationException('缺少凭据');
        }
        if(time() > $token['exp']) {
            throw new UnAuthorizationException('认证过期');
        }
        if(!key_exists('session', $token)) {
            throw new UnAuthorizationException('凭据无效');
        }
        $id = $token[$key];

        // if($session != $token['session']) {
        //     throw new UnAuthorizationException('用户已在其他设备登录');
        // }

        return $id;
    }


    /**
     * 认证
     * @param array $argv
     * @return mixed
     * @throws SystemException
     */
    public static function authenticate($argv = [])
    {
        if(!key_exists('jwt_key', $argv) || !is_string($argv['jwt_key']) || trim($argv['jwt_key']) == '')
            throw new Exception("need jwt_key string");
        if(!key_exists('jwt_token', $argv) || !is_array($argv['jwt_token']))
            throw new Exception("need token array");
        if(!key_exists('tag', $argv) || !is_string($argv['tag']) || trim($argv['tag']) == '')
            throw new Exception("need tag string");
        if(!key_exists('key', $argv) || !is_string($argv['key']) || trim($argv['key']) == '')
            throw new Exception("need key string");

        $jwtToken = $argv['jwt_token'];
        $jwtKey = $argv['jwt_key'];
        $key = $argv['key'];
        if(!key_exists($key, $jwtToken))
            throw new Exception("jwt_token must has key value");
        
        $session = uniqid();
        $jwtToken['session'] = $session;
        $jwt = JwtHandler::encode($jwtKey, $jwtToken);

        return $jwt;
    }

    /**
     * 取消认证
     * @param array $argv
     * @return mixed
     * @throws Exception
     */
    public static function cancelAuthenticate($argv = []) {
        if(!key_exists('tag', $argv) || !is_string($argv['tag']) || trim($argv['tag']) == '')
            throw new Exception("need tag string");
        if(!key_exists('key', $argv))
            throw new Exception("need key value");
        return true;
    }

}
